home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / asm / utils / fkey / fkey.asm next >
Encoding:
Assembly Source File  |  1980-01-04  |  10.9 KB  |  448 lines

  1. ;
  2. ; ### Function key handler by JM v 1.0 ###
  3. ;
  4. ; - Created 890125 by JM -
  5. ;
  6. ;
  7. ; This program links an input handler into the Input.device and converts
  8. ; the function key codes into ASCII strings.
  9. ;
  10. ;
  11. ;
  12. ;
  13. ; Bugs: yet unknown
  14. ;
  15. ;
  16. ; Edited:
  17. ;
  18. ; - 890125 by JM -> v0.01    - uh-huh
  19. ; - 890126 by JM -> v0.02    - first test
  20. ; - 890126 by JM -> v0.03    - replyport and sigbit really needed for
  21. ;                  DoIO().
  22. ; - 890126 by JM -> v0.04    - now allocates space for handler routine and
  23. ;                  key strings and creates a public message
  24. ;                  port.
  25. ; - 890126 by JM -> v0.05    - now allocates buffer for the generated
  26. ;                  input events.
  27. ; - 890126 by JM -> v0.06    - now generates the input events correctly.
  28. ; - 890126 by JM -> v0.07    - some minor changes.
  29. ; - 890126 by JM -> v0.08    - default fkey values added.
  30. ; - 890126 by JM -> v0.10    - comments improved.
  31. ; - 890127 by JM -> v0.11    - more keys defined.
  32. ; - 890127 by JM -> v1.0    - MESSAGE added.
  33. ;
  34. ;
  35.  
  36.  
  37.  
  38.         include    "exec.xref"
  39.         include    "dos.xref"
  40.         include    "JMPLibs.i"
  41.         include    "relative.i"
  42.         include    "com.i"
  43.         include    "string.i"
  44.         include    "exec/types.i"
  45.         include    "exec/nodes.i"
  46.         include    "exec/lists.i"
  47.         include    "exec/ports.i"
  48.         include    "exec/memory.i"
  49.         include    "exec/devices.i"
  50.         include    "exec/io.i"
  51.         include    "exec/tasks.i"
  52.         include    "devices/input.i"
  53.         include    "devices/inputevent.i"
  54.  
  55.  
  56. strcpy        macro    * a0,a1
  57. strcpy\@    move.b    (\1)+,(\2)+
  58.         bne.s    strcpy\@
  59.         endm
  60.  
  61.  
  62. RELATIVE    equ    1
  63.  
  64.         .var            allocates variables from stack
  65.         dl    _DosBase     using LINK a4,#-size
  66.         dl    iderror
  67.         dl    SignalB
  68.         dl    ioreq
  69.         dl    msgport
  70.         dl    globport
  71.  
  72.  
  73. start        .begin                this turns to LINK a4,#-NN
  74.         moveq.l    #-1,d0
  75.         move.l    d0,iderror(a4)
  76.         move.l    d0,SignalB(a4)
  77.         clr.l    _DosBase(a4)
  78.         clr.l    globport(a4)
  79.         lea    IORequest,a0
  80.         move.l    a0,ioreq(a4)
  81.         lea    MsgPort,a0
  82.         move.l    a0,msgport(a4)
  83.  
  84.         openlib    Dos,cleanup        open dos.library
  85.  
  86.         lea    indevname(pc),a0    input.device
  87.         moveq.l    #0,d0            unit#
  88.         move.l    ioreq(a4),a1        IoReq
  89.         moveq.l    #0,d1            flags
  90.         lib    Exec,OpenDevice
  91.         move.l    d0,iderror(a4)        flag: error if > 0
  92.         bne    cleanup            if error
  93.  
  94.         move.l    msgport(a4),a2
  95.         move.b    #NT_MSGPORT,LN_TYPE(a2)    msgport.mp_Node.ln_Type = 4
  96.         clr.b    MP_FLAGS(a2)        msgport.mp_Flags = 0
  97.         clr.l    LN_NAME(a2)        no name
  98.  
  99.         moveq.l    #-1,d0
  100.         lib    Exec,AllocSignal    get a signal bit
  101.         move.l    d0,SignalB(a4)
  102.         bmi    cleanup
  103.         move.b    d0,MP_SIGBIT(a2)    msgport.mp_SigBit = d0
  104.  
  105.         sub.l    a1,a1
  106.         flib    Exec,FindTask        find this task
  107.         move.l    d0,MP_SIGTASK(a2)    set msgport.mp_SigTask
  108.  
  109.         lea    MP_MSGLIST(a2),a0
  110.         NEWLIST    a0
  111.         move.l    ioreq(a4),a1
  112.         move.l    a2,MN_REPLYPORT(a1)    ioreq.io_Message.mn_ReplyPort
  113.  
  114.         lea    MESSAGE(pc),a0
  115.         printa    a0
  116.  
  117.         lea    portname(pc),a1        test if port already exists
  118.         lib    Exec,FindPort
  119.         move.l    d0,globport(a4)
  120.         bne    RemoveKeys        port exists -> remove everything
  121.  
  122.  
  123.  
  124. InstallKeys    bsr    CreatePort        create messageport
  125.         bcs    cleanup            -> can't CreatePort()
  126.  
  127.         bsr    AllocBuffer        allocate memory
  128.         beq    cleanup
  129.  
  130.         lea    MP_HANDLER(a2),a1    space for handler routine
  131.         lea    HANDBEG(pc),a0        source for copy
  132.         move.w    #HNDSIZ-1,d0        bytes to copy
  133. 1$        move.b    (a0)+,(a1)+
  134.         dbf    d0,1$
  135.  
  136.         lea    MP_FKEYS(a2),a0
  137.         move.l    a0,MP_DATA(a2)        set string buffer ptr
  138.  
  139.         lea    MP_HANDLER(a2),a0    a0 points to copy of hstuff
  140.         lea    HS_HANDLER(a0),a1
  141.         move.l    a1,HS_SERVER(a0)    set handler address
  142.         move.l    globport(a4),HS_PORT(a0) set port address
  143.  
  144.         move.l    ioreq(a4),a1
  145.         move.w    #IND_ADDHANDLER,IO_COMMAND(a1)
  146.         move.l    a0,IO_DATA(a1)
  147.         flib    Exec,DoIO        add handler
  148.         tst.l    d0
  149.         bne    cleanup
  150.  
  151.         bsr    defdef            set default fkey values
  152.  
  153.         lea    INSTALLED(pc),a0
  154.         printa    a0
  155.  
  156.         bra.s    cleanup
  157.  
  158.  
  159. RemoveKeys    move.l    ioreq(a4),a1
  160.         move.w    #IND_REMHANDLER,IO_COMMAND(a1)
  161.         move.l    d0,a0
  162.         lea    MP_HANDLER(a0),a0    addr of hstuff
  163.         move.l    a0,IO_DATA(a1)
  164.         lib    Exec,DoIO        remove handler
  165.         tst.l    d0
  166.         bne.s    cleanup
  167.  
  168.         lea    REMOVED(pc),a0        inform the user
  169.         printa    a0
  170.  
  171.         bsr    FreeBuffer        free allocated memory
  172.  
  173.         bsr    DeletePort        delete messageport
  174.  
  175. cleanup        move.l    iderror(a4),d0        test if input.device open
  176.         bne.s    cleanup10
  177.         move.l    ioreq(a4),a1
  178.         lib    Exec,CloseDevice    close input.device
  179.  
  180. cleanup10    move.l    SignalB(a4),d0        test if a signal allocated
  181.         bmi.s    cleanup11
  182.         lib    Exec,FreeSignal        if so, free it
  183.  
  184. cleanup11    closlib    Dos            close dos.library
  185.         moveq.l    #0,d0
  186.         .end                UNLK and RTS
  187.  
  188.  
  189.  
  190. *************************************************************************
  191. *                                    *
  192. * Create messageport so that the key strings etc. can be found by    *
  193. * other tasks like KEY.  Also needed to find the input handler and    *
  194. * to remove it from system when desired.                *
  195. *                                    *
  196. * This messageport stays in memory as long as the function keys are    *
  197. * active although the actual fkey program exits.  The buffers and    *
  198. * other variables immediately follow the standard MsgPort structure.    *
  199. *                                    *
  200. *************************************************************************
  201.  
  202. CreatePort    move.l    #MYPORT,d0
  203.         move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  204.         lib    Exec,AllocMem
  205.         move.l    d0,globport(a4)
  206.         beq.s    CreatePort_e
  207.         move.l    d0,a2
  208.         move.b    #0,LN_PRI(a2)
  209.         move.b    #NT_MSGPORT,LN_TYPE(a2)
  210.  
  211.         lea    MP_MYNAME(a2),a1    pos of name within myport
  212.         move.l    a1,LN_NAME(a2)
  213.         lea    portname(pc),a0
  214.         strcpy    a0,a1            copy name into myport
  215.  
  216.         move.l    a2,a1
  217.         flib    Exec,AddPort        AddPort!  - Crash!? - No.
  218.         clrc
  219.         rts
  220.  
  221. CreatePort_e    setc
  222.         rts
  223.  
  224.  
  225. DeletePort    lea    portname(pc),a1
  226.         lib    Exec,FindPort
  227.         move.l    d0,a1
  228.         move.l    d0,d2
  229.         beq.s    DeletePort_ok
  230.         flib    Exec,RemPort
  231.         move.l    #MYPORT,d0
  232.         move.l    d2,a1
  233.         flib    Exec,FreeMem
  234. DeletePort_ok    rts
  235.  
  236.  
  237.  
  238. *************************************************************************
  239. *                                    *
  240. * Allocate buffer for extra InputEvent structures created when the user    *
  241. * presses a function key.                        *
  242. * We don't use dynamic allocation to save some time in the input    *
  243. * handler routine.                            *
  244. *                                    *
  245. *************************************************************************
  246.  
  247. AllocBuffer    move.l    globport(a4),a2
  248.         move.l    #(64*ie_SIZEOF),d0
  249.         move.l    d0,MP_BUFSIZ(a2)
  250.         move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  251.         lib    Exec,AllocMem
  252.         move.l    d0,MP_BUFPTR(a2)
  253.         rts
  254.  
  255. FreeBuffer    move.l    globport(a4),a2
  256.         move.l    MP_BUFPTR(a2),d0
  257.         beq.s    FreeBuf_ok
  258.         move.l    d0,a1
  259.         move.l    MP_BUFSIZ(a2),d0
  260.         lib    Exec,FreeMem
  261.         clr.l    MP_BUFPTR(a2)
  262. FreeBuf_ok    rts
  263.  
  264.  
  265.  
  266. *************************************************************************
  267. *                                    *
  268. * Set default function key definitions:                    *
  269. *                                    *
  270. *************************************************************************
  271.  
  272. defdef        lea    deftable(pc),a0
  273.         move.l    globport(a4),a1
  274.         lea    MP_FKEYS(a1),a1
  275.         moveq.l    #19,d0            counter
  276. defloop1    lea.l    64(a1),a2        addr of next string
  277. defloop2    move.b    (a0)+,(a1)+
  278.         bpl.s    defloop2
  279.         move.l    a2,a1            next
  280.         dbf    d0,defloop1
  281.         rts
  282.  
  283.  
  284.  
  285. *************************************************************************
  286. *                                    *
  287. * My input handler routine.  It doesn't handle a linked list of input    *
  288. * events correctly because it only checks the first event of the list.    *
  289. * If the first one is a fkey the rest of the events in the queue are    *
  290. * discarded.  If the first event is not a fkey the list is passed    *
  291. * untouched to the next handler (ie. no later events are checked for    *
  292. * fkey codes).                                *
  293. *                                    *
  294. *************************************************************************
  295.  
  296. HANDBEG
  297.  
  298. hstuff        dc.l    0            ln_Succ
  299.         dc.l    0            ln_Pred
  300.         dc.b    2            ln_Type = NT_INTERRUPT
  301.         dc.b    60            ln_Pri
  302.         dc.l    0            ln_Name
  303. glport        dc.l    0            data
  304. hserver        dc.l    0            server
  305.  
  306. handler        push    d1-d7/a1-a6
  307.         move.l    a0,a5
  308.         cmpi.b    #IECLASS_RAWKEY,ie_Class(a0)
  309.         bne.s    handex
  310.         move.w    ie_Code(a0),d0
  311.         sub.w    #$50,d0
  312.         blo.s    handex
  313.         cmp.w    #$9,d0
  314.         bhi.s    handex
  315.         moveq.l    #IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT,d1 mask
  316.         and.w    ie_Qualifier(a0),d1    shift status
  317.         bsr.s    handlefkeys
  318.  
  319. handex        pull    d1-d7/a1-a6
  320.         move.l    a0,d0
  321.         rts
  322.  
  323. handlefkeys    tst.w    d1
  324.         beq.s    1$
  325.         add.w    #10,d0            -> shifted keys 10...19
  326. 1$        asl.w    #6,d0            calculate index into table
  327.         move.l    glport(pc),a0
  328.         move.l    MP_BUFPTR(a0),a1    buffer for input events
  329.         move.l    a1,a4            save it
  330.         lea    MP_FKEYS(a0),a0
  331.         add.w    d0,a0            pointer to fkey buffer
  332.         tst.b    (a0)
  333.         bmi.s    hndlfkeys_NULL        -> empty string
  334.  
  335.         moveq.l    #31,d2            char counter
  336.  
  337. hndl_next    clr.l    ie_NextEvent(a1)    initialize IEvent structure
  338.         move.b    #IECLASS_RAWKEY,ie_Class(a1)
  339.         clr.b    ie_SubClass(a1)
  340.         moveq.l    #0,d0
  341.         move.b    (a0)+,d0
  342.         move.w    d0,ie_Code(a1)
  343.         move.b    31(a0),d0
  344.         move.w    d0,ie_Qualifier(a1)
  345.         clr.l    ie_EventAddress(a1)
  346.         move.l    ie_TimeStamp(a5),ie_TimeStamp(a1)
  347.         move.l    ie_TimeStamp+4(a5),ie_TimeStamp+4(a1)
  348.         tst.b    (a0)
  349.         bmi.s    hndl_no_more        -> no more chars
  350.         subq.w    #1,d2
  351.         bmi.s    hndl_no_more
  352.         lea    ie_SIZEOF(a1),a2
  353.         move.l    a2,(a1)            set ptr to next ie
  354.         move.l    a2,a1
  355.         bra.s    hndl_next
  356.  
  357. hndl_no_more    move.l    a4,a0            -> return addr of new stream
  358.         rts
  359. hndlfkeys_NULL    sub.l    a0,a0            -> no events
  360.         rts
  361.  
  362. HANDEND
  363. HS_SERVER    equ    hserver-hstuff        define offsets
  364. HS_HANDLER    equ    handler-hstuff
  365. HS_PORT        equ    glport-hstuff
  366. HNDSIZ        equ    HANDEND-HANDBEG
  367.  
  368.  
  369.  
  370. *************************************************************************
  371. *                                    *
  372. * Allocate space within messageport for port name, function key strings *
  373. * and the handler routine.                        *
  374. *                                    *
  375. *************************************************************************
  376.  
  377. MP_DATA        equ    MP_SIZE            pointer to string buffer
  378. MP_HANDLER    equ    MP_DATA+4        space for handler routine
  379. MP_BUFPTR    equ    MP_HANDLER+HNDSIZ    input event buffer pointer
  380. MP_BUFSIZ    equ    MP_BUFPTR+4        input event buffer size
  381. MP_MYNAME    equ    MP_BUFSIZ+4        pointer to buffer
  382. MP_FKEYS    equ    MP_MYNAME+16        buffer for key strings
  383. MYPORT        equ    MP_FKEYS+1340        size of my msgport
  384.  
  385.  
  386.  
  387.  
  388. indevname    dc.b    'input.device',0
  389. portname    dc.b    'FKeyPort',0
  390. INSTALLED    dc.b    'FKeys installed',10,0
  391. REMOVED        dc.b    'FKeys removed',10,0
  392. MESSAGE        dc.b    'FKEY 1.0 by Supervisor Software 1989',10,0
  393.  
  394.  
  395. *************************************************************************
  396. *                                    *
  397. * Default function key definitions in raw key codes.            *
  398. * No qualifiers can be set here.                    *
  399. *                                    *
  400. *************************************************************************
  401.  
  402. deftable    dc.b    $36,$12,$11,$33,$28,$17,$44,-1       newcli<cr>
  403.         dc.b    $12,$36,$22,$33,$28,$17,$44,-1       endcli<cr>
  404.         dc.b    $22,$17,$13,$44,-1           dir<cr>
  405.         dc.b    $28,$17,$21,$14,$44,-1           list<cr>
  406.         dc.b    $33,$22,$40,-1               cd<spc>
  407.         dc.b    $13,$16,$36,$40,-1           run<spc>
  408.         dc.b    $12,$32,$12,$33,$16,$14,$12,$40,-1 execute<spc>
  409.         dc.b    $17,$36,$23,$18,$44,-1           info<cr>
  410.         dc.b    $20,$34,$20,$17,$28,$44,-1       avail<cr>
  411.         dc.b    $35,$13,$12,$20,$27,$40,-1       break<spc>
  412.         dc.b    -1            11
  413.         dc.b    -1            12
  414.         dc.b    -1            13
  415.         dc.b    -1            14
  416.         dc.b    -1            15
  417.         dc.b    -1            16
  418.         dc.b    -1            17
  419.         dc.b    -1            18
  420.         dc.b    -1            19
  421.         dc.b    -1            20
  422.  
  423.  
  424.  
  425. *************************************************************************
  426. *                                    *
  427. * This macro produces only the dos.library name in this program.    *
  428. *                                    *
  429. *************************************************************************
  430.  
  431.         libnames
  432.  
  433.  
  434.  
  435. *************************************************************************
  436. *                                    *
  437. * Structures defined in a bss chunk to make the program file smaller.    *
  438. *                                    *
  439. *************************************************************************
  440.  
  441.         section    struct,bss
  442.  
  443. IORequest    ds.b    IO_SIZE            struct IOStdReq
  444. MsgPort        ds.b    MP_SIZE            struct MsgPort
  445.  
  446.         end
  447.  
  448.